package com.sophialex.health.record.common.bind.swt.annotations;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import org.eclipse.ui.part.ViewPart;

import com.sophialex.health.record.common.bind.swt.annotations.helper.ObjMaker;

public class ListPathComboDataBindToProcessor extends ComboDataBindToProcessor {

	public ListPathComboDataBindToProcessor(ViewPart view, Field f,
			AnnotionProcessor parent) {
		super(view, f, parent);
	}

	@SuppressWarnings("unchecked")
	@Override
	protected Object computeBeanPropValue(Object bean, String[] beanPath) {
		String[] paths = beanPath;
		Object upper = bean;
		Pattern np = Pattern.compile("[0-9]+");

		Class<?> geniricType = null;
		for (int i = 0; i < paths.length; i++) {

			if (!np.matcher(paths[i]).matches()) {//paths[i]不是数字

				Object tmp = getFieldValue(upper, paths[i]);
				if (tmp == null) {//还未初始化

					Method m = null;
					Class<?> clazz = null;
					Field field = null;
					try {
						m = upper.getClass().getDeclaredMethod(
								"get"
										+ Character.toUpperCase(paths[i]
												.charAt(0))
										+ paths[i].substring(1));
						clazz = m.getReturnType();
						if (List.class.isAssignableFrom(clazz)) {
							String gs = m.getGenericReturnType().toString();
							geniricType = Class.forName(gs.split("<")[1]
									.split(">")[0]);
						} else {
							geniricType = null;
						}
					} catch (Exception e) {
						// e.printStackTrace();
					}

					// 若字段为空，为其赋新值
					if (m == null) {
						try {
							field = upper.getClass().getDeclaredField(paths[i]);
							clazz = field.getType();

							if (List.class.isAssignableFrom(clazz)) {
								String gs = field.getGenericType().toString();
								geniricType = Class.forName(gs.split("<")[1]
										.split(">")[0]);
							} else {
								geniricType = null;
							}

						} catch (Exception e) {
							e.printStackTrace();
							throw new BadBindingException("beanPath配置不正确！");
						}
					}
//					Constructor<?> c = null;
//					try {
//						if(clazz.equals(List.class))
//							c = ArrayList.class.getConstructor();
//						else
//							c = clazz.getConstructor();
//					} catch (Exception e) {
//						//e.printStackTrace();
//						System.out.println(clazz.getSimpleName()+"无缺少构造函数！");
//					}
					try {
//						if(clazz.equals(int.class) || clazz.equals(Integer.class)){
//							tmp = 0;
//						}else if(clazz.equals(long.class)|| clazz.equals(Long.class)){
//							tmp  = 0L;
//						}else{
//							tmp = c.newInstance();
//						}
						tmp = ObjMaker.getInstance(clazz).newObject();
						setFieldValue(upper, paths[i], tmp);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}else {
					if (List.class.isAssignableFrom(tmp.getClass())) {
						try {
							Method m = upper.getClass().getDeclaredMethod(
									"get"
											+ Character.toUpperCase(paths[i]
													.charAt(0))
											+ paths[i].substring(1));
							@SuppressWarnings("unused")
							Class clazz = m.getReturnType();
							
								String gs = m.getGenericReturnType().toString();
								geniricType = Class.forName(gs.split("<")[1]
										.split(">")[0]);
							
						} catch (Exception e) {
							e.printStackTrace();
						}
					}else{
						geniricType = null;
					}
				}
				//setFieldValue(upper, paths[i], tmp);
				upper = tmp;
			} else {// 数字
				int elementIndex = Integer.parseInt(paths[i]);
				List list = (List) upper;
				if (elementIndex > list.size()) {
					try {
						//Constructor<?> c = geniricType.getConstructor();
						ObjMaker maker = ObjMaker.getInstance(geniricType);
						int size = list.size();
						for (int ii = 0; ii < elementIndex-size; ii++) {
							list.add(maker.newObject());
						}
					} catch (Exception e) {

					}
				}
				upper = list.get(elementIndex-1);
				int j=i+1;
				for(;j<paths.length;j++){
					if(np.matcher(paths[j]).matches())break;
				}
				if(j != paths.length){
					geniricType = null;
				}
				
			}
		}
		return upper;
	}

	@Override
	protected void validatebeanPath(Class<?> parent, String curBeanPath) {
		Pattern p = Pattern.compile("[0-9]");
		String[] pathElements = curBeanPath.split("\\.");
		int i=0;
		for(;i<pathElements.length;i++){
			if (p.matcher(pathElements[i]).matches()) {// 数字
				break;
			}
		}
		if(i==pathElements.length){
			super.validatebeanPath(parent, curBeanPath);
			return;
		}
		doValidateBeanPath(parent, curBeanPath, null);
	}
	private void doValidateBeanPath(Class<?> parent, String curBeanPath,
			Class<?> geniricType) {
		String[] pathElements = curBeanPath.split("\\.");
		Pattern np = Pattern.compile("[0-9]+");
		if(np.matcher(pathElements[0]).matches())
		{
			String p = "";
			for(int i=1;i<pathElements.length;i++){
				p+="."+pathElements[i];
			}
			doValidateBeanPath(geniricType, p.substring(1),null);
			return;
		}
		Field beanField = null;
		List<Field> fs = getFields(parent, true);
		Class<?> gt = null;
		for(Field f : fs) {
			if(f.getName().equals(pathElements[0]))
				beanField = f;
		}
		if(beanField == null) {
			Method get = getMethods(parent, "get" + Character.toUpperCase(pathElements[0].charAt(0)) + pathElements[0].substring(1), true);
			if(get == null)
				throw new BadBindingException("beanPath设置有误:" + parent.getSimpleName() + "不存在名为'" + pathElements[0] + "'的字段！");
			else{
				if(List.class.isAssignableFrom(get.getReturnType())){
					try {
						gt = Class.forName(get.getGenericReturnType().toString().split("<")[1].split(">")[0]);
					} catch (ClassNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if(pathElements.length == 1) {
					lastElementType = get.getReturnType();
					return;
				} else {
					String newPath = curBeanPath.substring(curBeanPath.indexOf(".") + 1);
					doValidateBeanPath(get.getReturnType(), newPath,gt);
					return;
				}
			}
				
		}else{
			beanField.setAccessible(true);
			if(List.class.isAssignableFrom(beanField.getType())){
				try {
					gt = Class.forName(beanField.getGenericType().toString().split("<")[1].split(">")[0]);
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(pathElements.length == 1) {
				lastElementType = beanField.getType();
				return;
			} else {
				String newPath = curBeanPath.substring(curBeanPath.indexOf(".") + 1);
				doValidateBeanPath(beanField.getType(), newPath, gt);
				return;
			}
		}
		
	}
	private void setFieldValue(Object o, String fieldName, Object value) {
		Field f = null;
		List<Field> fs = getFields(o.getClass(), true);
		for (Field f1 : fs) {
			if (f1.getName().equals(fieldName))
				f = f1;
		}
		if (f != null) {
			f.setAccessible(true);
			try {
				f.set(o, value);
			} catch (Exception e) {
				e.printStackTrace();
				// System.exit(-1);
			}
			return;
		}

		String name = "set" + Character.toUpperCase(fieldName.charAt(0))
				+ fieldName.substring(1);
		parent.out(name + "\r\n");
		Method setter = null;
		try {

			setter = o.getClass().getMethod(name, value.getClass());

		} catch (Exception e1) {
			e1.printStackTrace();
			// System.exit(-1);// 没办法了，退出
		}
		try {

			setter.invoke(o, value);

		} catch (Exception e1) {
			e1.printStackTrace();
			// System.exit(-1);
		}

	}
	

}
